/*
 * Controller for taking care of the navigation
 */
package com.querie.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;


import com.querie.db.DBMSConnection;
import com.querie.parser.*;
import com.querie.collab.FrontEndProcessor;
import com.querie.util.ThreadFragment;
import com.querie.util.QryParameters;
import com.querie.pojo.QueryItemResult;
import com.querie.test.TestHarness;
import com.querie.test.TestHarnessButtonStatus;
import com.querie.test.ThreadClean;
import com.querie.test.ThreadSave;
import com.querie.test.ThreadTest;
import com.querie.test.ThreadTopK;
import com.querie.test.ThreadTrain;
import com.querie.util.AdminButtonStatus;

import java.sql.Connection;
import javax.servlet.http.HttpSession;

import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Enumeration;

/**
 *
 * @author a-skoshy
 * @author Duc On (ductuanon@hotmail.com)
 *
 */
public class ActionServlet extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            /* TODO output your page here
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet ActionServlet</title>");  
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet ActionServlet at " + request.getContextPath () + "</h1>");
            out.println("</body>");
            out.println("</html>");
             */
        } finally {
            out.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession(true);
        String action = request.getParameter("qAction");
        String task = request.getParameter("qTask");
        try {
            if (action.equals("admin")) {
                if (task.equals("LoadSchemaTables")) {
                    String startPattern = request.getParameter("matchStartStr");
                    String endPattern = request.getParameter("matchStopStr");
                    //DatabaseSchemaLoader loader = new DatabaseSchemaLoader(startPattern,endPattern);
                    //new Thread(loader).start();
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("SQLTest")) {
                    String text = request.getParameter("sqlExpr");
                    Connection con = DBMSConnection.getConnection();

                    //String text = "sElect top 20 * From field as f, zone as z where fieldid=0x08280ab2802c0000 order by ab";
                    ParserFactory qp = ParserFactory.getInstance();
                    Query q = new Query(text);
                    qp.parse(q, con);
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("ProcessQueriesFromDB")) {
                    new AdminButtonStatus().setBtnProcessStatus("disabled");
                    ThreadFragment doFrag = new ThreadFragment();
                    doFrag.start();
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("SetKValue")) {
                    QryParameters qryPara = QryParameters.getInstance();
                    qryPara.setValue("KVALUE", request.getParameter("kvalue"));
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("SetPrediction")) {
                    QryParameters qryPara = QryParameters.getInstance();
                    qryPara.setValue("PREDICTION", request.getParameter("prediction"));
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("SetCollaboration")) {
                    QryParameters qryPara = QryParameters.getInstance();
                    qryPara.setValue("ITEMORUSER", request.getParameter("collab"));
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("SetAlgo")) {
                    QryParameters qryPara = QryParameters.getInstance();
                    qryPara.setValue("ALGO", request.getParameter("algo"));
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("SetWeights")) {
                    QryParameters qryPara = QryParameters.getInstance();
                    qryPara.setValue("TABLEW", request.getParameter("tablew"));
                    qryPara.setValue("COLW", request.getParameter("colw"));
                    qryPara.setValue("WHEREW", request.getParameter("wherew"));
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("SetTopN")) {
                    QryParameters qryPara = QryParameters.getInstance();
                    qryPara.setValue("TOPN", request.getParameter("topn"));
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("SetSeparate")) {
                    QryParameters qryPara = QryParameters.getInstance();
                    qryPara.setValue("SEPARATE", request.getParameter("separate"));
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("SetTopQ")) {
                    QryParameters qryPara = QryParameters.getInstance();
                    qryPara.setValue("TOPQ", request.getParameter("topq"));
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("SetRemove")) {
                    QryParameters qryPara = QryParameters.getInstance();
                    qryPara.setValue("REMOVESAMEREC", request.getParameter("remove"));
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("SetNQueries")) {
                    QryParameters qryPara = QryParameters.getInstance();
                    qryPara.setValue("NUMTESTQUERYINSESSION", request.getParameter("nqueries"));
                    response.sendRedirect("admin.jsp");

                } else if (task.equals("EnableAllButtons")) {
                    QryParameters qryPara = QryParameters.getInstance();
                    qryPara.enableAllButtons();
                    response.sendRedirect("testHarness.jsp");

                } else if (task.equals("SubmitAll")) {
                    QryParameters qryPara = QryParameters.getInstance();
                    qryPara.setValue("KVALUE", request.getParameter("kvalue"));
                    qryPara.setValue("PREDICTION", request.getParameter("prediction"));
                    qryPara.setValue("ITEMORUSER", request.getParameter("collab"));
                    qryPara.setValue("ALGO", request.getParameter("algo"));
                    qryPara.setValue("TABLEW", request.getParameter("tablew"));
                    qryPara.setValue("COLW", request.getParameter("colw"));
                    qryPara.setValue("WHEREW", request.getParameter("wherew"));
                    qryPara.setValue("TOPN", request.getParameter("topn"));
                    qryPara.setValue("SEPARATE", request.getParameter("separate"));
                    qryPara.setValue("TOPQ", request.getParameter("topq"));
                    qryPara.setValue("REMOVESAMEREC", request.getParameter("remove"));
                    response.sendRedirect("admin.jsp");
                }

            } else if (action.equals("qryProc")) {
                if (task.equals("similCalc")) {
                    String txtQuery = request.getParameter("STxtQuery");
                    Integer sessionId = (Integer) session.getAttribute("sCustomerId");

                    QryParameters.getInstance().setValue("QRYPROCTIME", "0");
                    long start = System.currentTimeMillis();

                    FrontEndProcessor front = new FrontEndProcessor();
                    QueryItemResult result = front.processSimilarityAndQueryResults(sessionId, txtQuery); 
                    System.out.println("ActionServlet" + result);
                    long elapsedTimeSec = (System.currentTimeMillis() - start) / 1000;
                    QryParameters.getInstance().setValue("QRYPROCTIME", "" + elapsedTimeSec);

                    /*ItemSimilarity sim = null;
                    QryParameters qParam = QryParameters.getInstance();
                    String algoType = qParam.getValue("ALGO");
                    if (algoType.equals("jac")) {
                        sim = new JacItemSimilarity();
                    }else if (algoType.equals("cos")) {
                        sim = new CosineItemSimilarity();
                    }else{
                        throw new Exception("Unknown Algorithm");
                    }
                    QueryItemResult result = sim.findSimilarity(sessionId, txtQuery);*/
                    session.setAttribute("ItemResult", result);
                    session.setAttribute("STxtQuery", txtQuery);
                    //sim.close();

                    response.sendRedirect("queryItemResults.jsp");
                }

            } else if (action.equals("test")) {
                if (task.equals("saveSession")) {
                    //String txtQuery = request.getParameter("STxtQuery");
                    //Integer sessionId = (Integer) session.getAttribute("sCustomerId");

                    session.setAttribute("output", "Samples are saved.");

                    Dictionary dict = getElementsAsDictionary(request);
                    TestHarness.saveTestSet(dict);
                    //new TestHarnessButtonStatus().disableAllButtons();
                    //ThreadSave doSave = new ThreadSave(dict);
                    //doSave.start();

                    response.sendRedirect("testHarness.jsp");

                } else if (task.equals("runTrain")) {
                    // Get current time
                    // long start = System.currentTimeMillis();
                    // Do something ...
                    // TestHarness.processTrainingSet();
                    // Get elapsed time in milliseconds
                    // long elapsedTimeMillis = System.currentTimeMillis() - start;
                    // float elapsedTimeSec = elapsedTimeMillis / 1000F;
                    // session.setAttribute("output", "Training is completed and elapsed time is " + elapsedTimeSec);

                    // new TestHarnessButtonStatus().disableAllButtons();
                    QryParameters.getInstance().disableAllButtons();
                    ThreadTrain doTrain = new ThreadTrain();
                    doTrain.start();

                    response.sendRedirect("testHarness.jsp");

                } else if (task.equals("runTest")) {                    
                    QryParameters.getInstance().setValue("TESTTIME", "0");
                    long start = System.currentTimeMillis();

                    List<QueryItemResult> results = TestHarness.processTestSet();

                    long elapsedTimeSec = (System.currentTimeMillis() - start) / 1000;
                    QryParameters.getInstance().setValue("TESTTIME", "" + elapsedTimeSec);

                    session.setAttribute("output", "Item Similarity Calculation is completed.");
                    session.setAttribute("testResults", results);

                    //new TestHarnessButtonStatus().disableAllButtons();
                    //ThreadTest doTest = new ThreadTest(session);
                    //doTest.start();

                    response.sendRedirect("testHarnessResults.jsp");
                    //response.sendRedirect("testHarness.jsp");

                } else if (task.equals("runTopK")) {
                    //TestHarness.processTopK();
                    //session.setAttribute("output", "Top K Selected");

                    //new TestHarnessButtonStatus().disableAllButtons();
                    QryParameters.getInstance().disableAllButtons();
                    ThreadTopK doTopK = new ThreadTopK();
                    doTopK.start();

                    response.sendRedirect("testHarness.jsp");

                } else if (task.equals("runClean")) {
                    TestHarness.processClean();
                    session.setAttribute("output", "Database is cleaned.");
                    //new TestHarnessButtonStatus().disableAllButtons();
                    //ThreadClean doClean = new ThreadClean();
                    //doClean.start();                   

                    response.sendRedirect("testHarness.jsp");                    
                }
            }
        } catch (Exception e) {
            e.printStackTrace();

            session.setAttribute("sMessage", e.getMessage());
            response.sendRedirect("Error.jsp");
        }
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    public Dictionary getElementsAsDictionary(HttpServletRequest request) {
        Enumeration e = request.getParameterNames();

        Dictionary result = new Hashtable();
        String paramName, paramValue;
        while (e.hasMoreElements()) {
            paramName = ((String) e.nextElement()).trim();
            paramValue = ((String) request.getParameter(paramName)).trim();
            result.put(paramName, paramValue);
            System.out.println(paramName + " " + paramValue);
        }

        return result;
    }
}
